package wu.seal.utils

import java.awt.Desktop
import java.io.File
import kotlin.system.exitProcess

//日志目录默认当前目录
var logDir = File(".")

val filesDeal = FileDeal()

const val logFileMatch = ".*.log"

var fileNameMatchContent = ".*"

var lineMatchContent: String = ".*"

val helpTips = """
                |
                |------------------------快速取日志工具----------------------------
                |
                |这个工具可以快速取出叮咚或说道的相关日志并生成整合版本日志文件且自动打开查看
                |
                |支持以下情境
                |
                |1.直接取出Support问题附件中随带的压缩包中的日志并自动打开查看
                |2.可以在任何文件夹中快速取出日志并自动打开查看
                |3.可以快速取出手机中的叮咚PN1和说道PN1的日志并自动打开查看
                |
                |这个工具有三个参数并且都是可选项: [dirPath|zipPath|-pt|-pd|-ptd|-pdd|-pte|-pted] [fileNameFilterKey] [lineFilter]
                |
                |第一个参数支持以下七种类型的参数
                |zipPath:   要提取日志的的zip压缩包路径，如果为空，则代表直接在当前文件夹中提取日志
                |后面几个-p开头的参数均需要当前系统环境支持adb指令
                |-pt:       此为固定字符，代表是从手机里取出说道PN1的日志
                |-ptd:      此为固定字符，代表是从手机里取出说道DN1的日志
                |-pd:       此为固定字符，代表是从手机里取出叮咚PN1的日志
                |-pdd:      此为固定字符，代表是从手机里取出叮咚DN1的日志
                |-pte:      此为固定字符，代表是从手机里取出Telos PN1的日志
                |-pted:     此为固定字符，代表是从手机里取出Telos DN1的日志
                |
                |
                |fileNameFilterKey： 日志文本文件的文件名匹配规则，支持正则表达式
                |lineFilter：        过滤每一行文本，提取出符合匹配规则的文本，支持正则表达式
                |
                |（要查看此帮助信息，可以执行：`dtlog`）
                |
                |使用示例：
                |
                |$ dtlog /seal/log/2018-11-03-22-01.zip 03-22 login
                |此命令为从/seal/log/2018-11-03-22-01.zip文件中提取出满足文件名匹配`03-22`且行文本内容包括`login`的所有日志内容，
                |并会使用当前系统的默认文本查看器来查看提取出来的日志
                |
                |----------------------------------------------------------------
                |
            """.trimMargin()

/**
 * 将日志zip文件包移到临时文件夹中，并将日志目录指向临时目录
 */
fun copyLogZipFileToTempDirAndResetLogDirToTempDir(zipFilePath: String) {
    logDir = filesDeal.getWorkDirTempDir(logDir)
    platformPrint("将转移到新的临时目录下做日志解析：${logDir.absolutePath}")
    val zipFile = File(zipFilePath)
    val targetFile = zipFile.copyTo(File(logDir, zipFile.name), true)
    platformPrint("已经将日志zip移到文件夹：${targetFile.absolutePath} 下")
}

fun String.isZipFilePath() = endsWith(".zip")


/**
 * 将手机日志文件拉取到临时文件夹中，并将临时文件夹作为日志解析目录
 */
fun pullPhoneLogAndResetLogDirToTempDir(phoneLogCommend: String) {
    logDir = filesDeal.getWorkDirTempDir(logDir)
    platformPrint("将转移到新的临时目录下做日志解析：${logDir.absolutePath}")
    copyPhoneLog(phoneLogCommend, logDir.absolutePath)
    platformPrint("从手机上拉取日志文件成功")
}

/**
 * 脚本启动程序入口
 */
fun start(args: Array<String>) {
    when {
        args.isEmpty() -> {
            platformPrint(helpTips)
            exitProcess(0)
        }
        args.size == 1 -> {
            consumeFirstArgument(args[0])
        }
        args.size == 2 -> {
            //如果是zip日志文件
            consumeFirstArgument(args[0])
            consumeSecondArgument(args[1])
        }
        args.size == 3 -> {
            //如果是zip日志文件
            consumeFirstArgument(args[0])
            consumeSecondArgument(args[1])
            consumeThirdArgument(args[2])
        }
    }

    platformPrint("current logDir is ${logDir.absolutePath}")

    while (filesDeal.containsZip(logDir)) {
        filesDeal.unzipAllFilesRecursiveAndDeleteZipedFiles(logDir)
    }
    platformPrint("解压${logDir.name}目录下的所有zip文件成功")

    filesDeal.removeAllMacCacheFiles(logDir)

    platformPrint("删除${logDir.name}目录下的所有Mac缓存文件成功")

    val files = filesDeal.getAllFilesInDir(logDir.absolutePath)

    val logFiles = files.filter {
        val b = logFileMatch.toRegex().matches(it.name)
        platformPrint("${it.name} 是日志文件吗(日志文件以.log 结尾)?  : $b")
        b
    }

    val tobeCatFiles = filesDeal.getMatchesNameFiles(logFiles, fileNameMatchContent).sorted()

    with(tobeCatFiles){
        if (isEmpty()) {
            platformPrint("没有找到任何匹配文件")
        }
    }
    val logFile = obtainNewLogFile(cmdArgs = args)
    var hasMatchedContent = false
    var lines = 0
    val tobeShowInConsole = StringBuffer()
    tobeCatFiles.forEach {
        val sb = StringBuffer()
        it.readLines(charset("utf-8")).forEachIndexed { index, line ->
            val b = lineMatchContent.toRegex(RegexOption.IGNORE_CASE).containsMatchIn(line)
            if (b) {
                val appendFileNameLine = it.name.substringBeforeLast(".") + "\t" + line
                sb.appendln(appendFileNameLine)
                lines++
                if (lines <= 20) {
                    tobeShowInConsole.appendln(appendFileNameLine)
                }
                hasMatchedContent = true
            }
        }
        logFile.appendText(sb.toString())
    }

    if (hasMatchedContent) {
        logFile.appendText("======================================================developed by seal==============================================================")
    }
    if (logDir.absolutePath != File(".").absolutePath) {//当日志目录不是当前工作目录,说明是临时目录,可以放心删除所有临时文件
        logDir.deleteRecursively()
        platformPrint("清理临时文件成功")
    }

    if (hasMatchedContent) {

        if (lines <= 20) {
            platformPrint(tobeShowInConsole.toString())
        } else {

            if (nowInMacRuntime()) {
                Runtime.getRuntime().exec(arrayOf("open", logFile.absolutePath))
            } else if (nowInWindowsRuntime()) {
                Desktop.getDesktop().open(logFile);
            }
        }

    } else {
        platformPrint("没有找到任何匹配内容")
    }
}

private fun consumeThirdArgument(textLineMatchStyle: String) {
    lineMatchContent = textLineMatchStyle
    platformPrint("行文本匹配规则为： $lineMatchContent")
}

private fun consumeSecondArgument(fileMatchStyle: String) {
    fileNameMatchContent = fileMatchStyle
    platformPrint("日志文件名匹配规则为： $fileNameMatchContent")
}

private fun consumeFirstArgument(firstArg: String) {
    when {
        //如果是zip日志文件
        firstArg.isZipFilePath() -> copyLogZipFileToTempDirAndResetLogDirToTempDir(firstArg)
        firstArg.isPhoneLogCommend() -> pullPhoneLogAndResetLogDirToTempDir(firstArg)
        else -> {
            logDir = File(firstArg)
            platformPrint("要提取日志的日志目录为： ${logDir.absolutePath}")
        }
    }
}



